#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>

int main()
{
  pid_t id = fork();
  if(id == 0) {
    printf("I am a process!\n");
    sleep(3);
    //调用excel改变当前执行程序，如果调用成功就不会执行后续代码
    //execl("/usr/bin/ls","ls","-a","-i","-l",NULL);
    //excel("/usr/bin/top","top",NULL);
    
    //execlp第一个参数代表要执行谁，编译器会自动去环境变量里寻找
    //后面的参数代表要怎么执行
    //execlp("ls","ls","-a","-i","-l",NULL);
    
    char *myargv[] = {
      "ls",
      "-a",
      "-i",
      "-l",
      NULL
    };
    char *myenv[] = {
      "MYENV=youcanseemeHAHA",
      NULL
    };
    //execv("/usr/bin/ls",myargv);
    //execvp("ls",myargv);
    
    //如果要运行的程序就在本目录，就可以按下面这样写
    execle("./cmd","cmd",NULL,myenv);
    
    //execl("./test.sh","test.sh");
    //execl("./test.py","test.py");
    exit(10);
  }


  int status = 0;
  pid_t ret = waitpid(id,&status,0);
  if(ret > 0) {
    //打印终止信号
    printf("signal:%d\n",status&0x7F);
    //打印退出码
    printf("exit code:%d\n",(status>>8) & 0xFF);
  }


  //printf("I am a process!\n");
  //sleep(5);
  ////execl会从磁盘选取一个程序替换成当前程序
  ////第一个参数是程序路径，第二个是程序名字，最后一个参数以NULL结尾
  //execl("/usr/bin/ls","ls","-a","-i","-l",NULL);
  ////execl("/usr/bin/top","top",NULL);
  //exit(1);
  ////上面完成进程替换后，后续就不会执行了
  ////程序如果替换失败，后续代码不会受影响
  ////execl系列函数不需要返回值，有返回值就说明调用失败
  //printf("you can see me!\n");


  //pid_t id = fork();
  //if(id == 0) {
  //  //child
  //  int count = 0;
  //  while(count < 10) {
  //    printf("I am child,pid:%d,ppid:%d\n",getpid(),getppid());
  //    count++;
  //    sleep(3);
  //  }
  //  exit(1);
  //}
  ////到这就是父进程在子进程运行期间等待
  //while(1) {
  //  int status = 0;
  //  //将等待结果返回给ret，ret>0说明等待成功
  //  pid_t ret = waitpid(id,&status,WNOHANG);
  //  if(ret > 0) {
  //    //等待成功，子进程也已经结束了，直接退出
  //    printf("wait success!\n");
  //    printf("exit code:%d\n",WEXITSTATUS(status));
  //    break;
  //  }
  //  else if (ret == 0) {
  //    //子进程没有结束,继续等待,父进程可以干其他事
  //    printf("father do other thing!\n");
  //    sleep(1);
  //  }
  //  else {
  //    //获取退出码失败，即等待失败，直接退出
  //    printf("waitpid error!\n");
  //    break;
  //  }
  //}

  return 0;
}
